package App.Controller;

import App.Model.Contact_Group;
import App.Model.Contact_Message;
import App.Model.UserData;
import App.Public.Lib.DataExport;
import App.Public.Lib.PingYingUtil;
import App.Public.UI.Handler;
import App.Public.UI.StarButton;
import App.Public.UI.checkbox;
import App.Public.controller;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.BorderPane;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;

import static App.Public.UI.SimpleDialog.simpleConfirmDialog;
import static App.Public.UI.SimpleDialog.simpleErrorDialog;

public class MainController extends controller implements Initializable
{
    @FXML public BorderPane rootPane;
    @FXML public MenuButton button_MoveToGroup;
    @FXML public MenuButton button_CopyToGroup;
    @FXML public CheckBox choseAllBox;
    @FXML public CheckMenuItem phoneCheckMenuItem;
    @FXML public CheckMenuItem emailCheckMenuItem;
    @FXML public CheckMenuItem sexCheckMenuItem;
    @FXML public CheckMenuItem birthdayCheckMenuItem;
    @FXML public CheckMenuItem QQCheckMenuItem;
    @FXML public CheckMenuItem petNameCheckMenuItem;
    @FXML public CheckMenuItem homeAddressCheckMenuItem;
    @FXML public CheckMenuItem companyCheckMenuItem;
    public Menu menu_TableView;
    public Menu menu_System;
    @FXML private ListView<String> groupList;
    @FXML private TableView<TableData> table;
    @FXML private TableColumn<TableData,CheckBox> checkList;
    @FXML private TableColumn<TableData,String> fullName;
    @FXML private TableColumn<TableData,String> petName;
    @FXML private TableColumn<TableData,String> QQ;
    @FXML private TableColumn<TableData,String> sex;
    @FXML private TableColumn<TableData,String> birthday;
    @FXML private TableColumn<TableData,String> homeAddress;
    @FXML private TableColumn<TableData,String> company;
    @FXML private TableColumn<TableData,String> tel;
    @FXML private TableColumn<TableData,String> email;
    @FXML private TableColumn<TableData,String> group;
    @FXML private ListView<String> contactList;
    @FXML private TextField query;
    @FXML private TableColumn<TableData,Button> starList;

    /**
     * 登录成功用户的对象
     */
    private UserData user=(UserData) DATA.getData("userData");
    /**
     * 所有联系人的表示
     */
    private final String AllUserExpression="所有联系人";
    /**
     * 未分组联系人的表示
     */
    private final String UserWithNoGroup="未分组联系人";
    /**
     * 星标联系人的表示
     */
    private final String StarGroup="星标联系人";
    /**
     * 禁止对list中的元素进行操作
     */
    public String[] banList={AllUserExpression,};

    public MainController() throws Exception {}

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        try {
            //controller.DATA.register("chosenList",new ArrayList<>());
            controller.DATA.register("table",table);
            controller.DATA.register("groupList",groupList);
            controller.DATA.register("contactList",contactList);
            controller.DATA.register("stageList",new ArrayList<Stage>());
            controller.DATA.register("mainController",this);
        } catch (Exception e) {
            e.printStackTrace();
        }

        loadCss(rootPane,"MainView.css");
        initMenu();
        try {
            initTable();
        } catch (Exception e) {
            e.printStackTrace();
        }
        listenCloseEvent();
        initGroupList();
        listenGroupChange();
        listenContactGroupChange();
        //初始化默认选择所有联系人
        contactList.getSelectionModel().select(AllUserExpression);


        query.textProperty().addListener( (event)->{ //搜索栏添加动态监听器
                search();
            });

        query.setOnKeyPressed((event) -> { //搜索栏添加回车Enter按键监听器
            if(event.getCode() == KeyCode.ENTER) {
                try {
                    search();
                } catch (Exception ignored){}
            }
        });

    }

    /**
     * 初始化menu
     */
    public void initMenu(){
        initCheckMenuItem(phoneCheckMenuItem,tel);
        initCheckMenuItem(emailCheckMenuItem,email);
        initCheckMenuItem(sexCheckMenuItem,sex);
        initCheckMenuItem(birthdayCheckMenuItem,birthday);
        initCheckMenuItem(QQCheckMenuItem,QQ);
        initCheckMenuItem(petNameCheckMenuItem,petName);
        initCheckMenuItem(homeAddressCheckMenuItem,homeAddress);
        initCheckMenuItem(companyCheckMenuItem,company);
    }

    /**
     * 对表格初始化
     * @throws Exception
     */
    public void initTable() throws Exception {
        checkList.setCellValueFactory(cellData -> cellData.getValue().getCheckBox());
        starList.setCellValueFactory(cellData ->cellData.getValue().getStart().getStartButton());
        fullName.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getPerson().getFullName()));
        petName.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getPerson().getPetName()));
        sex.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getPerson().getSex()));
        tel.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getPerson().getPhoneNumberList().toString()));
        email.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getPerson().getEmailList().toString()));
        QQ.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getPerson().getQQ()));
        birthday.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getPerson().getBirthday()));
        group.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getPerson().getGroup().toString()));
        homeAddress.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getPerson().getHomeAddress()));
        company.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getPerson().getCompany()));
        table.setItems(FXCollections.observableArrayList(TableData.getDataList(user.getPersonBase())));

        controller.DATA.register("ContactNow");

        //设置事件
        table.setRowFactory( tv -> {
            TableRow<TableData> row = new TableRow<>();
            row.setOnMouseClicked(event -> {
                //双击事件
                if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
                    Contact_Message rowData = row.getItem().getPerson();
                    try {
                        controller.DATA.setData("ContactNow",rowData);
                        Stage stage = showXML("编辑联系人","fxml_EditContact.fxml",new Stage());

                        ArrayList<Stage> stageList = (ArrayList<Stage>) controller.DATA.getData("stageList");
                        stageList.add(stage);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    System.out.println(rowData);
                }
                //右键事件
                if (event.getButton() == MouseButton.SECONDARY && (! row.isEmpty()) ) {
                    Contact_Message rowData = row.getItem().getPerson();
                    MenuItem menu_Edit = new MenuItem("编辑联系人");
                    menu_Edit.setOnAction(event1 -> {
                        try {
                            controller.DATA.setData("ContactNow",rowData);
                            Stage stage = showXML("编辑联系人","fxml_EditContact.fxml",new Stage());

                            ArrayList<Stage> stageList = (ArrayList<Stage>) controller.DATA.getData("stageList");
                            stageList.add(stage);
                        } catch (Exception ignored) {}
                        System.out.println(rowData);
                    });
                    MenuItem menu_Remove = new MenuItem("删除联系人");
                    menu_Remove.setOnAction(event1 -> {
                        //Remove the chosen Contact
                        removeContactAction(new ActionEvent());
                    });
                    tv.setContextMenu(new ContextMenu(menu_Edit,menu_Remove));

                }
            });
            return row ;
        });

    }


    /**
     * 对分组列表进行初始化
     */
    public void initGroupList()
    {
        ArrayList<String> groupNameList=user.getGroupNameList();
        //groupNameList.add(0,AllUserExpression);
        groupList.setItems(FXCollections.observableArrayList(groupNameList));
        groupList.setCellFactory(tv -> {
            ListCell<String> cell = new ListCell<>();
            cell.textProperty().bind(cell.itemProperty());
            cell.setOnMouseClicked(event -> {
                if (event.getButton() == MouseButton.SECONDARY && (! cell.isEmpty()) ) {
                    MenuItem menu_Edit = new MenuItem("编辑组名");
                    //menu_Edit.textProperty().bind(Bindings.format("Edit \"%s\"", cell.itemProperty()));
                    menu_Edit.setOnAction(event1 -> editGroupAction(new ActionEvent()));
                    MenuItem menu_Remove = new MenuItem("删除组");
                    menu_Remove.setOnAction(event1 -> {
                        //Remove the chosen Contact
                        removeGroupAction(new ActionEvent());
                    });
                    tv.setContextMenu(new ContextMenu(menu_Edit,menu_Remove));

                }
            });
            return cell ;
        });
    }

    /**
     * 对联系人列表进行初始化
     */
    public void listenContactGroupChange(){
        contactList.getItems().add(StarGroup);
        contactList.getSelectionModel().selectedItemProperty().addListener(event ->{
            String selectedItem=contactList.getSelectionModel().getSelectedItem();
            if(selectedItem==null)
            {   //处理取消选择的情况
                return;
            }
            //取消分组列表的选择
            groupList.getSelectionModel().clearSelection();
            try {
                switch (selectedItem) {
                    case AllUserExpression:
                        //如果点击的是所有联系人,则返回所有人的信息
                        showPersonBase();
                        break;
                    case UserWithNoGroup:
                        showData(user.getPersonBaseWithNoGroup());
                        break;
                    case StarGroup:
                        showData(user.getStarList());
                        ObservableList<TableData> list = table.getItems();
                        //如何点击星号则将对应联系人在表格移除（不是删除）
                        //只在选择星号联系人的时候才监听
                        for (TableData item : list) {
                            item.getStart().addListenToStart((observable, oldValue, newValue) ->
                                table.getItems().remove(item));
                        }
                        break;
                }
            }
            catch(Exception e)
            {
                //不处理
            }
        });

    }

    /**
     * 监听分组列表点击事件
     */
    public void listenGroupChange() {
        groupList.getSelectionModel().selectedItemProperty().addListener(event ->{

            String selectedGroup = groupList.getSelectionModel().getSelectedItem();
            if(selectedGroup==null)
            {   //处理取消选择的情况
                return;
            }
            //取消联系人列表的选择
            contactList.getSelectionModel().clearSelection();
            try {
                if(selectedGroup.equals(AllUserExpression))
                {
                    //如果点击的是所有联系人,则返回所有人的信息
                    showPersonBase();
                }
                else
                {
                    showGroup(selectedGroup);
                }


            } catch (Exception e) {
               // e.printStackTrace();
            }
        });
    }

    @FXML
    public void AddContact(ActionEvent actionEvent) throws Exception {
        String groupNow = groupList.getSelectionModel().getSelectedItem();
        if(groupNow != null)
            controller.DATA.setData("ContactNow", new Contact_Message(user.getUsername(), groupNow)); //把新的新的Contact替换到DATA中，此时已setGroup和userName
        else { //未分组
            controller.DATA.setData("ContactNow", new Contact_Message(user.getUsername())); //把新的新的Contact替换到DATA中，此时已setUserName,没有分组
            if(contactList.getSelectionModel().getSelectedIndex() == 2)
                contactList.getSelectionModel().select(1);
        }
            Stage stage = showXML("新建联系人","fxml_AddContact.fxml",new Stage());

        ArrayList<Stage> stageList = (ArrayList<Stage>) controller.DATA.getData("stageList");
        stageList.add(stage);
    }

    @FXML
    public void search()
    {
        String condition=query.getText();
        if(condition.equals("")) {
            showPersonBase();
        }
        else {
            table.getItems().clear();
            ArrayList<Contact_Message> result=user.search(condition);
            result.sort(sortByPingYing);
            table.getItems().addAll(TableData.getDataList(result));
        }
    }

    @FXML
    public void addGroupAction(ActionEvent actionEvent) {
        TextInputDialog dialog = new TextInputDialog("");
        dialog.setContentText("输入新分组");
        dialog.setHeaderText("");
        dialog.setTitle("新建组");

        Optional<String> result = dialog.showAndWait();
        if (result.isPresent()){
            String text = result.get().replaceAll(" ","");
            if (!text.equals("")) {
                try {
                    user.addGroup(result.get()); //user在开头已取值
                    ArrayList<String> groupNameList = user.getGroupNameList();
                    groupList.getItems().add(result.get());
                } catch (Exception e) {
                    Alert alert =new Alert(Alert.AlertType.ERROR);
                    alert.setTitle("添加分组错误");
                    alert.setHeaderText(null);
                    alert.setContentText(e.toString());
                    alert.showAndWait();
                }
            }
        }
    }

    @FXML
    public void editGroupAction(ActionEvent actionEvent) {
        if(groupList.getSelectionModel().getSelectedItem()==null)
        {
            simpleErrorDialog("请选择你要编辑的组").showAndWait();
            return;
        }
        String groupNow;
        try {
            groupNow = groupList.getSelectionModel().getSelectedItem();
            if (groupNow.equals("未分组") || groupNow.equals(AllUserExpression))
                throw new Exception("不可修改的组");
            TextInputDialog dialog = new TextInputDialog("");
            dialog.setContentText("输入新组名");
            dialog.setHeaderText("");
            dialog.setTitle("修改组名");

            Optional<String> result = dialog.showAndWait();
            final String finalGroupNow = groupNow;
            result.ifPresent(newGroupName -> {
                String text = newGroupName.replaceAll(" ","");
                if (!text.equals("")) {
                    try {
                        if(user.hasGroup(newGroupName))
                        {
                            //如果编辑的新组名已经存在,则弹出选择框是否两个组合并
                            Alert alert=new Alert(Alert.AlertType.CONFIRMATION);
                            alert.setTitle("编辑组名警告");
                            alert.setHeaderText("注意");
                            alert.setContentText(newGroupName+"已经存在，请选择是否合并对应的小组");
                            Optional<ButtonType> option=alert.showAndWait();
                            if(option.get()==ButtonType.OK)
                            {
                                //将两个小组合并,将要编辑的组合并到重名的小组那里
                                ArrayList<Contact_Message> people = user.getGroup(finalGroupNow).getGroup();
                                Contact_Group newGroup=user.getGroup(newGroupName);
                                for(Contact_Message person:people)
                                {
                                    newGroup.addMember(person);
                                }
                                user.modifyGroupName(finalGroupNow,newGroupName);
                                user.removeGroup(finalGroupNow);
                            }
                        }
                        else
                        {
                            Contact_Group nowGroup=user.getGroup(finalGroupNow);
                            user.modifyGroupName(finalGroupNow, newGroupName); //user在开头已取值
                            user.removeGroup(finalGroupNow);
                            user.addGroup(newGroupName,nowGroup);
                        }

                        ArrayList<String> groupNameList = user.getGroupNameList();
                        groupList.setItems(FXCollections.observableArrayList(groupNameList));
                        groupList.getSelectionModel().select(newGroupName);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        catch (Exception e){
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            alert.setTitle("警告");
            alert.setHeaderText(null);
            alert.setContentText(e.toString().replace("java.lang.Exception:",""));
            alert.showAndWait();
        }

    }

    @FXML
    public void moveToGroupAction()
    {
        shiftGroup();
    }

    public void shiftGroup()
    {
        button_MoveToGroup.getItems().clear();
        for(String group:user.getGroupNameList())
        {
            MenuItem item =new MenuItem(group);
            //item被选中绑定的事件
            item.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    String fromGroup;
                    fromGroup = groupList.getSelectionModel().getSelectedItem();
                    String toGroup=item.getText();
                    Contact_Message selectedPerson=null;
                    if(table.getSelectionModel().getSelectedItem()!=null)
                    {
                        selectedPerson = table.getSelectionModel().getSelectedItem().getPerson();
                    }
                    ArrayList<Contact_Message> selectedList = checkChosen();

                    if(selectedPerson==null && selectedList.size() == 0) {
                        Alert error=simpleErrorDialog("请选择你要移动的联系人");
                        error.showAndWait();
                        return;
                    }
                    if (contactList.getSelectionModel().getSelectedItem() != null)
                        fromGroup = "未分组";
//                    user.addPersonToGroup(finalSelectedPerson,toGroup);
//                    if(fromGroup==null) {
//                        Alert error=simpleErrorDialog("请选择你要移动的联系人所在分组");
//                        error.showAndWait();
//                        return;
//                    }
                    Contact_Message finalSelectedPerson = selectedPerson;

                    final String finalFromGroup = fromGroup;
                    Handler okAction=new Handler() {
                        @Override
                        public void run() {
                            if (selectedList.size() == 0) {
                                try {
                                    if (!finalFromGroup.equals("未分组"))
                                        user.shiftPersonToGroup(finalSelectedPerson, finalFromGroup, toGroup);
                                    else user.addPersonToGroup(finalSelectedPerson, toGroup);
                                } catch (Exception e) {
                                    simpleErrorDialog(e.toString()).showAndWait();
                                }
                            }
                            else {
                                    for (Contact_Message selectedContact : selectedList) {
                                        try {
                                            clearSelect();
                                            if (!finalFromGroup.equals("未分组"))
                                                user.shiftPersonToGroup(selectedContact, finalFromGroup, toGroup);
                                            else user.addPersonToGroup(selectedContact, toGroup);
                                        } catch (Exception e) {
                                            simpleErrorDialog(e.toString()).showAndWait();
                                        }
                                    }

                            }
                            //移动完成后会跳到ToGroup
                            groupList.getSelectionModel().select(toGroup);
                        }
                    };
                        simpleConfirmDialog("所选人将从"+fromGroup+"移动到"+toGroup,okAction);
                }
            });
            button_MoveToGroup.getItems().add(item);
        }
        button_MoveToGroup.show();
    }

    @FXML
    public void CopyToGroupAction()
    {
        button_CopyToGroup.getItems().clear();

        for(String item:user.getGroupNameList())
        {
            MenuItem bt=new MenuItem(item);
            bt.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    String toGroup=bt.getText();
                    Contact_Message selectedPerson = null;
                    if(table.getSelectionModel().getSelectedItem()!=null)
                    {
                        selectedPerson = table.getSelectionModel().getSelectedItem().getPerson();
                    }
                    //获得选取的所有联系人的列表
                    ArrayList<Contact_Message> selectedList = checkChosen();

                    if(selectedPerson==null  && selectedList.size() == 0)
                    {
                        Alert error=simpleErrorDialog("请选择你要复制的联系人");
                        error.showAndWait();
                        return;
                    }
                    //确认框按确认后的动作
                    Contact_Message finalSelectedPerson = selectedPerson;
                    Handler okAction=new Handler() {
                        @Override
                        public void run() {
                            if (selectedList.size() == 0) {
                                try {
                                    user.addPersonToGroup(finalSelectedPerson,toGroup);
                                    //复制完成后会跳到ToGroup的选项，相当于刷新
                                    groupList.getSelectionModel().select(toGroup);
                                    table.getItems().clear();
                                    try {
                                        showGroup(toGroup);
                                    } catch (Exception ignored) {}
                                } catch (Exception e) {
                                    Alert error=simpleErrorDialog(e.toString().replace("java.lang.Exception:",""));
                                    error.showAndWait();
                                }
                            }
                            else {
                                    for (Contact_Message selectedContact : selectedList){
                                        clearSelect();
                                        try{
                                            user.addPersonToGroup(selectedContact,toGroup);
                                        } catch (Exception e) {
                                            Alert error=simpleErrorDialog(e.toString().replace("java.lang.Exception:",""));
                                            error.showAndWait();
                                        }
                                    }

                                //复制完成后会跳到ToGroup的选项，相当于刷新
                                groupList.getSelectionModel().select(toGroup);
                                table.getItems().clear();
                                try
                                {
                                    showGroup(toGroup);
                                } catch (Exception e) {}
                            }

                        }
                    };
                    simpleConfirmDialog("所选人将复制到"+toGroup,okAction);
                }
            });
            button_CopyToGroup.getItems().add(bt);

        }
        button_CopyToGroup.show();
    }

    @FXML
    public void removeContactAction(ActionEvent actionEvent) {
        String selectedGroup=groupList.getSelectionModel().getSelectedItem();
        Contact_Message selectedPerson=null;
        if(table.getSelectionModel().getSelectedItem()!=null)
        {
            selectedPerson = table.getSelectionModel().getSelectedItem().getPerson();
        }


        ArrayList<Contact_Message> selectedList = checkChosen();

        if (selectedPerson == null && selectedList.size() == 0) {
            Alert error=simpleErrorDialog("请选择你要删除的联系人");
            error.showAndWait();
            return;
        }
        if (contactList.getSelectionModel().getSelectedItem() != null){
            //如果选择所有联系人或未分组联系人，将分组指向所有联系人，将执行彻底删除
            selectedGroup = AllUserExpression;
        }
        if (selectedGroup == null) {
            Alert error=simpleErrorDialog("请选择你要删除的联系人所在分组");
            error.showAndWait();
            return;
        }

        if (selectedList.size() == 0)
            removeContact(selectedGroup,selectedPerson);
        else
            removeContact(selectedGroup,selectedList);

        //删除完成后会跳到组选项，相当于刷新
        if (selectedGroup == AllUserExpression){
            contactList.getSelectionModel().select(AllUserExpression);
            showPersonBase();
        }
        else {
            groupList.getSelectionModel().select(selectedGroup);
            try {
                showGroup(selectedGroup);
            } catch (Exception ignored) {}
        }
    }

    /**
     * 删除一个人
     * @param selectedGroup 所选择的组（String表示）
     * @param selectedPerson 单选所选中的联系人
     */
    private void removeContact(String selectedGroup,Contact_Message selectedPerson){
        if(selectedGroup.equals(AllUserExpression))
        {   //如果选择全部人，则彻底删除
            Handler okAction=new Handler() {
                @Override
                public void run() {
                    user.removePerson(selectedPerson);
                }
            };
            simpleConfirmDialog(selectedPerson.getFullName()+"将在"+AllUserExpression+"删除",okAction);
        }
        else
        {
            //如果选择某个分组，则只会删除对应小组
            Handler okAction=new Handler() {
                @Override
                public void run()  {
                    try {
                        user.getGroup(selectedGroup).removePerson(selectedPerson);
                    } catch (Exception e) {
                        simpleErrorDialog(e.toString()).showAndWait();
                    }
                }
            };
            simpleConfirmDialog(selectedPerson.getFullName()+"将在"+selectedGroup+"删除",okAction);
        }
    }

    /**
     * 删除多个人
     * @param selectedGroup 所选择的组（String表示）
     * @param selectedList 多选所选中的联系人列表
     */
    private void removeContact(String selectedGroup,ArrayList<Contact_Message> selectedList){

            if(selectedGroup.equals("所有联系人")) {
                Handler okAction= () -> {
                    for(Contact_Message selectedPerson : selectedList) {
                        user.removePerson(selectedPerson);
                    }
                };
                simpleConfirmDialog("选中人将在所有联系人中删除",okAction);
            } else {
                Handler okAction= () -> {
                    for(Contact_Message selectedPerson : selectedList) {
                        try {
                            user.getGroup(selectedGroup).removePerson(selectedPerson);
                        } catch (Exception e) {
                            simpleErrorDialog(e.toString()).showAndWait();
                        }
                    }
                };
                simpleConfirmDialog("选中人将在"+selectedGroup+"删除",okAction);
            }
    }

    @FXML
    public void removeGroupAction(ActionEvent actionEvent) {

        String selectedGroup=groupList.getSelectionModel().getSelectedItem();
        if(selectedGroup==null)
        {
            simpleErrorDialog("请选择你要删除的分组").showAndWait();
            return;
        }
        for(String item:banList)
        {   //判断被选中的小组是否在banList中
            if(selectedGroup.equals(item))
            {
                simpleErrorDialog(selectedGroup+"不允许被删除").showAndWait();
                return;
            }
        }
        //进行删除操作
        Handler okAction=new Handler() {
            @Override
            public void run() {
                try {
                    user.removeGroup(selectedGroup);
                } catch (Exception e) {
                    simpleErrorDialog(e.toString()).showAndWait();
                }
                //删除完成后会刷新分组列表和表格
                initGroupList();
                groupList.getSelectionModel().select(0);
                showPersonBase();
            }
        };
        simpleConfirmDialog(selectedGroup+"将会被删除（组内联系人将会移入未分组）",okAction);


    }

    @FXML
    public void exportAction() {
        FileChooser f=new FileChooser();

        f.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("xls", "*.xls"),
                new FileChooser.ExtensionFilter("csv", "*.csv"),
                new FileChooser.ExtensionFilter("vcf","*.vcf")
        );

        File file =f.showSaveDialog(new Stage());
        String path=file.toString();
        ArrayList<Contact_Message> list=TableData.getPersonList(table.getItems());
        //ArrayList<Object> list=new ArrayList<>(table.getItems());
        String suffix=path.substring(path.lastIndexOf('.')+1,path.length());
        System.out.println(suffix);
        //先判断路径是否含有合法的后缀
        try {
            switch (suffix) {
                case "xls":
                    DataExport.objectListToXls(list, path);
                    return;
                case "csv":
                    DataExport.objectListToCsv(list, path);
                    return;
                case "vcf":
                    DataMiddleWare.exportVcard(list, path);
                    return;

            }
            //如果不存在合法的路径，就由选择的类型决定输出哪种格式
            String type = f.getSelectedExtensionFilter().getDescription();

            switch (type) {
                case "xls":
                    DataExport.objectListToXls(list, path);
                    return;
                case "csv":
                    DataExport.objectListToCsv(list, path);
                    return;
                case "vcf":
                    DataMiddleWare.exportVcard(list, path);
                    return;
            }
        }
        catch (Exception e)
        {
            simpleErrorDialog(e.toString()).showAndWait();
        }
    }

    @FXML
    public void importAction()
    {
        int successAdd=0;
        FileChooser f=new FileChooser();

        f.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("vcf","*.vcf"),
                new FileChooser.ExtensionFilter("csv","*.csv")
        );

        File file =f.showOpenDialog(new Stage());
        String path=file.toString();
        String suffix=path.substring(path.lastIndexOf('.')+1,path.length());
        //根据路径来确定导入的类型
        try {
            switch (suffix) {
                case "vcf":
                    successAdd=importFromVcard(path);
                    break;
                case "csv":
                    successAdd=importFromCsv(path);
                    break;
                default:
                    simpleErrorDialog("请选择vcf文件或者csv文件").showAndWait();
                    return;
            }
        }
        catch (Exception e)
        {
            simpleErrorDialog(e.toString()).showAndWait();
        }
        Handler okAction=new Handler() {
            @Override
            public void run() {
                //如果导入了就跳到全部联系人那里重新载入数据
                refresh();
            }
        };
        simpleConfirmDialog("成功导入了"+successAdd+"位联系人",okAction);

    }

    /**
     * 从Vcard里面导入数据到user的联系人列表里面
     * @param path  vcf文件的路径
     * @return      成功导入的人数
     * @throws Exception
     */
    public int importFromVcard(String path) throws Exception
    {
        ArrayList<Contact_Message>list=new ArrayList<>();
        list.addAll(DataMiddleWare.importVcard(path));
        for(Contact_Message person:list)
        {
            user.addPerson(person);
        }
        return list.size();
    }

    /**
     * 从csv里面导入数据到user的联系人列表里面
     * @param path vcf文件的路径
     * @return      成功导入的人数
     * @throws Exception
     */
    public int importFromCsv(String path) throws Exception
    {
        int AddSuccess=0;
        ArrayList<Contact_Message>list=DataMiddleWare.importCsv(path);
        for(Contact_Message person:list)
        {
            try{
                user.addPerson(person);
                AddSuccess++;
            }
            catch(Exception e)
            {
                System.out.println(e.toString());
            }

        }
        return AddSuccess;
    }
    @FXML
    public void choseAll(ActionEvent actionEvent) {
        ObservableList<TableData> list = table.getItems();

        boolean checkBoxState = choseAllBox.isSelected();
            for (TableData o : list) {
                    o.getCheckBox().getValue().setSelected(checkBoxState);
            }
    }

    @FXML
    public void Management(ActionEvent actionEvent) throws Exception {
        Stage stage = showXML("账户管理","fxml_Management.fxml",new Stage());

        ArrayList<Stage> stageList = (ArrayList<Stage>) controller.DATA.getData("stageList");
        stageList.add(stage);
    }

    public void listenCloseEvent()
    {
        Stage AppStage= null;
        try {
            AppStage = getAppStage();
        } catch (Exception e) {
            simpleErrorDialog(e.toString()).showAndWait();
        }
        Stage finalAppStage = AppStage;

        if (AppStage == null) return ;

        AppStage.setOnCloseRequest(event -> {

            Handler okAction= () -> {
                try {
                    //确认就保存对象并且关闭窗口
                    user.save();
                        ArrayList<Stage> stageList = null;
                        try {
                            stageList = (ArrayList<Stage>) controller.DATA.getData("stageList");
                        } catch (Exception ignored) {}
                    if (stageList != null) {
                        stageList.forEach(Stage::close);
                    }
                    finalAppStage.close();
                } catch (IOException e) {
                    simpleErrorDialog(e.toString()).showAndWait();
                }
            };
            event.consume();
            simpleConfirmDialog("你确定要退出程序吗",okAction);
        });

    }

    /**
     * 用户登出功能
     */
    @FXML
    public void userLogOut()
    {
        simpleConfirmDialog("请确认是否要切换账号", () -> {
                try {
                    //确认就保存对象并且关闭窗口
                    user.save();
                    ArrayList<Stage> stageList = null;
                    try {
                        stageList = (ArrayList<Stage>) controller.DATA.getData("stageList");
                    } catch (Exception ignored) {}
                    if (stageList != null) {
                        stageList.forEach(Stage::close);
                    }
                    showAPP("Pathway通讯录-登陆","fxml_LoginView.fxml",getAppStage());
                } catch (IOException e) {
                    simpleErrorDialog(e.toString()).showAndWait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
//            try {
//                showAPP("login","fxml_LoginView.fxml",getAppStage());
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
        });

    }
    /**
     * 表格显示所有联系人的数据
     */
    public void showPersonBase()
    {
        table.getItems().clear();
        table.getItems().addAll(TableData.getDataList(user.getPersonBase()));
    }

    /**
     * 表格显示对应分组的数据
     */
    public void showGroup(String groupName) throws Exception
    {
        table.getItems().clear();
        ArrayList<Contact_Message> list=user.getGroup(groupName).getGroup();
        list.sort(sortByPingYing);
        table.getItems().addAll(TableData.getDataList(list));
    }

    public void showData(ArrayList<Contact_Message> data)
    {
        table.getItems().clear();
        data.sort(sortByPingYing);
        table.getItems().addAll(TableData.getDataList(data));
    }
    public void refresh()
    {
        contactList.getSelectionModel().selectFirst();
        groupList.getItems().clear();
        groupList.getItems().addAll(user.getGroupNameList());
        showPersonBase();
    }


    /**
     * 获取所勾选的人
     * @return 所选人的ArrayList
     */
    private ArrayList<Contact_Message> checkChosen()
    {
        ObservableList<TableData> list = table.getItems();
        ArrayList<Contact_Message> chosenList = new ArrayList<>();
        for(TableData o : list) {
            if(o.isSelected()) {
                chosenList.add(o.getPerson());
            }
        }
        return chosenList;
    }

    /**
     * 清除勾选
     */
    public void clearSelect()
    {
        for(TableData item:table.getItems())
        {
            item.setSelected(false);
        }
    }

    /**
     * 比较拼音的sort方法
     */
    Comparator<Contact_Message> sortByPingYing = new Comparator<Contact_Message>() {
        @Override
        public int compare(Contact_Message o1, Contact_Message o2)
        {
            return PingYingUtil.getFullSpell(o1.getFullName()).compareTo(PingYingUtil.getFullSpell(o2.getFullName()));
        }

        @Override
        public boolean equals(Object obj) {
            return false;
        }
    };

    /**
     * 初始化多选目录
     * @param cmi checkMenuItem项
     * @param column 表格列
     */
    private void initCheckMenuItem(CheckMenuItem cmi,TableColumn column){
        //加载用户配置
        if (user.getConflict(cmi.getText()).equals("true")) {
            cmi.setSelected(true);
            showTableColumn(column);
        }
        else {
            cmi.setSelected(false);
            hideTableColumn(column);
        }
        setCheckMenuItemListener(cmi,column);
    }

    /**
     * CheckMenuItem添加监听事件
     * @param cmi checkMenuItem项
     * @param column 表格列
     */
    private void setCheckMenuItemListener (CheckMenuItem cmi,TableColumn column){
        cmi.selectedProperty().addListener(
                (ObservableValue<? extends Boolean> ov, Boolean old_val, Boolean new_val) -> {
                    if (new_val)
                        showTableColumn(column);
                    else
                        hideTableColumn(column);
                    user.setAndSaveConflict(cmi.getText(),new_val.toString()); //修改配置
                });
    }

    /**
     * 收起列
     * @param column 表格列
     */
    private void hideTableColumn(TableColumn column){
        column.setMinWidth(0);
        column.setPrefWidth(0);
        column.setResizable(false);
    }

    /**
     * 展示列
     * @param column 表格列
     */
    private void showTableColumn(TableColumn column){
        column.setMinWidth(50);
        column.setPrefWidth(200);
        column.setResizable(true);
    }
}

/**
 * 表格单元数据
 * 包括checkBox，星标，Contact_Message
 */
class TableData
{
    //将数据包装一层，这样就不会影响到model
    private Contact_Message person;
    private checkbox box;
    private StarButton start;

    public Handler handler=new Handler() {
        @Override
        public void run() {
            person.setStar(start.isSelected());
            System.out.println(person.getFullName()+person.getIsStart());
        }
    };
    public TableData(Contact_Message p)
    {
        this.person=p;
        box=new checkbox();
        start=new StarButton(handler);
        start.setSelected(person.getIsStart());
    }

    /**
     * 将联系人对象数组转化为包装数据的对象数组
     */
    public static ArrayList<TableData> getDataList(ArrayList<Contact_Message> list)
    {
        ArrayList<TableData> result=new ArrayList<>();
        for(Contact_Message item :list)
        {
            result.add(new TableData(item));
        }
        return result;
    }
//    return list.stream().map(TableData::new).collect(Collectors.toCollection(ArrayList::new));

//    ArrayList<TableData> result = list.stream().map(TableData::new).collect(Collectors.toCollection(ArrayList::new));
//    return result;

    public Contact_Message getPerson()
    {
        return this.person;
    }

    /**
     * 代理checkbox函数
     */
    public ObservableValue<CheckBox> getCheckBox()
    {
        return this.box.getCheckBox();
    }

    public boolean isSelected()
    {
        return this.box.isSelected();
    }

    public void setSelected(Boolean o)
    {
        this.box.checkbox.setSelected(o);
    }

    public static ArrayList<Contact_Message> getPersonList(List<TableData> data)
    {
        ArrayList<Contact_Message>result=new ArrayList<>();
        for(TableData item:data)
        {
            result.add(item.getPerson());
        }
        return result;
    }
    public StarButton getStart()
    {
       return this.start;
    }

}